﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LumenWorks.Framework.IO.Csv;

namespace DataProcessor.Core
{
    public static class IEnumerableExtensions
    {
        /// <summary>
        /// Convert a comma separated IEnumerable of lines to field value dictionary
        /// </summary>
        /// <param name="source">IEnumerable of csv including header</param>
        /// <returns></returns>
        public static IEnumerable<Dictionary<string, string>> ToCsvDictionary(this IEnumerable<string> source)
        {
            return ToCsvDictionary(source, ',');
        }
        
        /// <summary>
        /// Convert a [deliminator] separated IEnumerable of lines to field value dictionary
        /// </summary>
        /// <param name="source">IEnumerable of csv including header</param>
        /// <param name="deliminator">Deliminator character</param>
        /// <returns></returns>
        public static IEnumerable<Dictionary<string, string>> ToCsvDictionary(this IEnumerable<string> source, char deliminator)
        {
            var fields = source.Take(1).FirstOrDefault().Split(deliminator);
            return source.Skip(1)
                .Select(line => line.Split(deliminator)
                    .Zip(fields, (value, field) => new KeyValuePair<string, string>(field, value))
                    .ToDictionary(i => i.Key, i => i.Value));
        }

        /// <summary>
        /// Convert a CsvReader object to csv field value dictionar
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static IEnumerable<Dictionary<string, string>> ToCsvDictionary(this CsvReader source)
        {
            if (!source.HasHeaders)
                throw new Exception("Can not create Csv Dictionary from a CsvReader without headers.");

            var fields = source.GetFieldHeaders();
            return source.Select(row => row.Zip(fields, (value, field) => new KeyValuePair<string, string>(field, value))
                    .ToDictionary(i => i.Key, i => i.Value));
        }

    }
}
